import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_web_view/widget/f_webview/webview_controller.dart';
import 'package:flutter_web_view/widget/f_webview/webview_strategy.dart';

/// InAppWebView 实现
class InAppWebViewStrategy extends StatefulWidget implements WebViewStrategy {
  const InAppWebViewStrategy({
    Key? key,
    required this.initialUrl,
    this.onTitleChanged,
    this.onWebViewCreated,
    this.onProgressChanged,
    this.onLoadStop,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return InAppWebViewStrategyState();
  }

  @override
  final String initialUrl;

  @override
  final void Function(FWebViewController controller, String? url)?
      onTitleChanged;

  @override
  final void Function(FWebViewController controller)? onWebViewCreated;

  @override
  final void Function(FWebViewController controller, int progress)?
      onProgressChanged;

  @override
  final void Function(FWebViewController controller, String? url)? onLoadStop;
}

class InAppWebViewStrategyState extends State<InAppWebViewStrategy>
    implements FWebViewController {
  InAppWebViewController? _webViewController;

  final InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
    crossPlatform: InAppWebViewOptions(
      useShouldOverrideUrlLoading: true,
      mediaPlaybackRequiresUserGesture: false,
    ),

    /// android 支持HybridComposition
    android: AndroidInAppWebViewOptions(
      useHybridComposition: true,
    ),
    ios: IOSInAppWebViewOptions(
      allowsInlineMediaPlayback: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return InAppWebView(
      initialUrlRequest: URLRequest(url: Uri.parse(widget.initialUrl)),
      initialOptions: options,
      onTitleChanged: (InAppWebViewController controller, String? title) {
        if (widget.onTitleChanged != null) {
          widget.onTitleChanged!(this, title);
        }
      },
      onWebViewCreated: (InAppWebViewController controller) {
        _webViewController = controller;
        if (widget.onWebViewCreated != null) {
          widget.onWebViewCreated!(this);
        }
      },
      onLoadStop: (InAppWebViewController controller, Uri? url) {
        String loadUrl;
        if (url == null) {
          loadUrl = "";
        } else {
          loadUrl = url.toString();
        }
        if (widget.onLoadStop != null) {
          widget.onLoadStop!(this, loadUrl);
        }
      },
      onProgressChanged: (InAppWebViewController controller, int progress) {
        if (widget.onProgressChanged != null) {
          widget.onProgressChanged!(this, progress);
        }
      },
    );
  }

  @override
  Future<bool> canGoBack() {
    if (_webViewController == null) {
      return Future.sync(() => false);
    }
    return _webViewController!.canGoBack();
  }

  @override
  Future<bool> canGoForward() {
    if (_webViewController == null) {
      return Future.sync(() => false);
    }
    return _webViewController!.canGoForward();
  }

  @override
  Future<void> goBack() {
    if (_webViewController == null) {
      return Future.sync(() => null);
    }
    return _webViewController!.goBack();
  }

  @override
  Future<void> goForward() {
    if (_webViewController == null) {
      return Future.sync(() => null);
    }
    return _webViewController!.goForward();
  }

  @override
  Future<String?> getUrl() {
    if (_webViewController == null) {
      return Future.sync(() => null);
    }
    return _webViewController!.getUrl().then((uri) => uri.toString());
  }

  @override
  Future<String?> getTitle() {
    if (_webViewController == null) {
      return Future.sync(() => null);
    }
    return _webViewController!.getTitle();
  }

  @override
  Future<void> loadUrl(String url) {
    if (_webViewController == null) {
      return Future.sync(() => null);
    }
    return _webViewController!
        .loadUrl(urlRequest: URLRequest(url: Uri.parse(url)));
  }

  @override
  Future<void> reload() {
    if (_webViewController == null) {
      return Future.sync(() => null);
    }
    return _webViewController!.reload();
  }
}
